/**
 * axios 二次封装
 */

import axios from "axios";
import config from "../config";
import router from "../router";
import { ElMessage } from "element-plus";

const TOKEN_INVSLID = "Token认证失败，请重新登录";
const NETWORK_ERROR = "网络请求异常，请稍后重试";

// 创建 axios 实例对象，添加全局配置
const service = axios.create({
  baseURL: config.baseApi,
  timeout: 8000,
});

// 请求拦截
service.interceptors.request.use((req) => {
  // TODO
  const headers = req.headers;
  if (!headers.Authorization) {
    headers.Authorization = "Bear Jack";
  }
  return req;
});

// 响应拦截
service.interceptors.response.use((res) => {
  const { code, data, msg } = res.data;
  switch (code) {
    // 正常
    case 200:
      return data;
      break;
    // 权限校验失败
    case 40001:
      ElMessage.error(TOKEN_INVSLID);
      setTimeout(() => {
        router.push("./login");
      }, 1000);
      return Promise.reject(TOKEN_INVSLID);
      break;
    default:
      ElMessage.error(msg || NETWORK_ERROR);
      return Promise.reject(msg || NETWORK_ERROR);
      break;
  }
});

/**
 * 请求核心函数
 * @param {Object} options 请求配置
 */
const request = (options) => {
  // 默认使用 GET 请求
  options.method = options.method || "get";

  // 转小写做判断
  if (options.method.toLowerCase() === "get") {
    options.params = options.data;
  }

  // 判断是否存在局部 mock 存在的话以局部 mock 为主覆盖全局 mock
  if (typeof options.mock !== "undefined") {
    config.mock = options.mock;
  }

  // 各环境的请求地址设置
  switch (config.env) {
    case "prod":
      service.defaults.baseURL = config.baseApi;
      break;
    default:
      service.defaults.baseURL = config.mock ? config.mockApi : config.baseApi;
      break;
  }

  return service(options);
};

// 给函数绑上几个基础的请求方法
["get", "post", "put", "delete", "patch"].forEach((method) => {
  request[method] = (url, data, options) => {
    return request({
      url,
      method,
      data,
      ...options,
    });
  };
});

export default request;
